#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>


int main(int argc, char **argv)
{
    void *handle;
    int (*sort)(int*, int);
    char *error;

    if(2 != argc) {
        fprintf(stderr, "%s\n", "usage : sortcall filepath.");
        exit(EXIT_FAILURE);
    }

    handle = dlopen(argv[1], RTLD_LAZY);
    if (!handle) {
        fprintf(stderr, "%s\n", dlerror());
        exit(EXIT_FAILURE);
    }

    dlerror();    /* Clear any existing error */

    /* Writing: cosine = (double (*)(double)) dlsym(handle, "cos");
    would seem more natural, but the C99 standard leaves
    casting from "void *" to a function pointer undefined.
    The assignment used below is the POSIX.1-2003 (Technical
    Corrigendum 1) workaround; see the Rationale for the
    POSIX specification of dlsym(). */

    *(void **) (&sort) = dlsym(handle, "sort_a");

    if ((error = dlerror()) != NULL)  {
        fprintf(stderr, "%s\n", error);
        exit(EXIT_FAILURE);
    }

    int a[6] = {1, 4, 6, 3, 2, 1};

    (*sort)(a, 6);

    int i;
    for(i=0; i<6; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");

    dlclose(handle);
    exit(EXIT_SUCCESS);
}
